﻿using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Runtime.Caching;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Mt.Site.Application.Common.Dto;
using Mt.Site.Application.ContentManagement.FrontEnd;
using Mt.Site.Application.Dto.Add;
using Mt.Site.Core.ContentManagement.Entities;
using Mt.Site.Core.Messages_;
using Mt.Site.Core.Navigations.Entities;
using Mt.Site.Core.Navigations.Values;
using Mt.Site.Core.Storage;
using Mt.Site.Core.Url;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mt.Site.Application.Common
{
    public class FrontendEtcAppService : MtSiteFrontendAppServiceBase, IFrontendEtcAppService
    {

        private readonly ICacheManager _cacheManager;

        private ITypedCache<long, List<ChannelObjectDto>> MenuInfoCache
            => _cacheManager.GetCache<long, List<ChannelObjectDto>>(ApiCacheNames.MenuInfoCache);

        private readonly IRepository<ChannelObject, Guid> _channelObjectRepository;

        private readonly IHttpContextAccessor _httpContextAccessor;


        public FrontendEtcAppService(
            ICacheManager cacheManager,
            IRepository<ChannelObject, Guid> channelObjectRepository,
            IHttpContextAccessor httpContextAccessor)
        {
            _cacheManager = cacheManager;
            _channelObjectRepository = channelObjectRepository;
            _httpContextAccessor = httpContextAccessor;
        }

        public async Task<GetMenuInfoDataOutput> GetMenuInfoDataAsync(MenuAndIdInput<Guid> input)
        {
            var data = await MenuInfoCache.GetAsync(input.MenuId, async () =>
            {
                return await GetMenuInfoDataInternalAsync(input);
            });


            return new GetMenuInfoDataOutput
            {
                Data = data,
                Now = DateTime.Now.ToUnixTimeByMilliseconds(),
                IsMobile = UrlChecker.IsMobile(_httpContextAccessor.HttpContext)
            };
        }

        private async Task<List<ChannelObjectDto>> GetMenuInfoDataInternalAsync(MenuAndIdInput<Guid> input)
        {
            var now = DateTime.Now.ToUnixTimeByMilliseconds();

            // time1 上架时间，time2 下架时间
            List<ChannelObject> list2 = await _channelObjectRepository.GetAll()
                        .Where(c => c.MenuId == input.Id 
                            && c.IsActive == true 
                            && (c.Time1 == 0 || c.Time1 <= now)
                            && (c.Time2 == 0 || c.Time2 >= now))
                        .OrderByDescending(c => c.Order)
                        .ThenByDescending(c=>c.CreationTime)
                        .ToListAsync();

            return ObjectMapper.Map<List<ChannelObjectDto>>(list2);
        }
    }
}
